using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Text;
using System.Xml;
using UnityEngine;

public static class Utility
{
	private static System.Random m_Random = new System.Random();
	private static Encoding m_UTF8, m_UTF8WithEncoding;

	public static Encoding UTF8
	{
		get
		{
			if (m_UTF8 == null)
				m_UTF8 = new UTF8Encoding(false, false);

			return m_UTF8;
		}
	}

	public static Encoding UTF8WithEncoding
	{
		get
		{
			if (m_UTF8WithEncoding == null)
				m_UTF8WithEncoding = new UTF8Encoding(true, false);

			return m_UTF8WithEncoding;
		}
	}

	#region Get[Something]
	public static int GetInt32(string intString, int defaultValue)
	{
		try
		{
			return XmlConvert.ToInt32(intString);
		}
		catch
		{
			try
			{
				return Convert.ToInt32(intString);
			}
			catch
			{
				return defaultValue;
			}
		}
	}

	public static DateTime GetDateTime(string dateTimeString, DateTime defaultValue)
	{
		try
		{
			return XmlConvert.ToDateTime(dateTimeString, XmlDateTimeSerializationMode.Local);
		}
		catch
		{
			DateTime d;

			if (DateTime.TryParse(dateTimeString, out d))
				return d;

			return defaultValue;
		}
	}

	public static TimeSpan GetTimeSpan(string timeSpanString, TimeSpan defaultValue)
	{
		try
		{
			return XmlConvert.ToTimeSpan(timeSpanString);
		}
		catch
		{
			return defaultValue;
		}
	}

	public static string GetAttribute(XmlElement node, string attributeName)
	{
		return GetAttribute(node, attributeName, null);
	}

	public static string GetAttribute(XmlElement node, string attributeName, string defaultValue)
	{
		if (node == null)
			return defaultValue;

		XmlAttribute attr = node.Attributes[attributeName];

		if (attr == null)
			return defaultValue;

		return attr.Value;
	}

	public static string GetText(XmlElement node, string defaultValue)
	{
		if (node == null)
			return defaultValue;

		return node.InnerText;
	}

	public static int GetAddressValue(IPAddress address)
	{
#pragma warning disable 618
		return (int)address.Address;
#pragma warning restore 618
	}

	public static long GetLongAddressValue(IPAddress address)
	{
#pragma warning disable 618
		return address.Address;
#pragma warning restore 618
	}
	#endregion

	public static int RandomList(params int[] list)
	{
		return list[m_Random.Next(list.Length)];
	}

	public static bool RandomBool()
	{
		return (m_Random.Next(2) == 0);
	}

	public static int RandomMinMax(int min, int max)
	{
		if (min > max)
		{
			int copy = min;
			min = max;
			max = copy;
		}
		else if (min == max)
		{
			return min;
		}

		return min + m_Random.Next((max - min) + 1);
	}

	public static int Random(int from, int count)
	{
		if (count == 0)
		{
			return from;
		}
		else if (count > 0)
		{
			return from + m_Random.Next(count);
		}
		else
		{
			return from - m_Random.Next(-count);
		}
	}

	public static int Random(int count)
	{
		return m_Random.Next(count);
	}

	public static double RandomDouble()
	{
		return m_Random.NextDouble();
	}

	public static Point3D GetRandomPoint3D(int sizeX, int sizeY, int sizeZ)
	{
		int x = Utility.Random(sizeX);
		int y = Utility.Random(sizeY);
		int z = Utility.Random(sizeZ);

		return new Point3D(x, y, z);
	}

	public static string Intern(string str)
	{
		if (str == null)
			return null;
		else if (str.Length == 0)
			return String.Empty;

		return String.Intern(str);
	}

	public static void Intern(ref string str)
	{
		str = Intern(str);
	}

	public static string GetUniqueStarName()
	{
		string name = NameList.RandomName("Star");

		return name;
	}

	public static string GetUniqueMaleName()
	{
		string name = NameList.RandomName("Male");

		return name;
	}

	public static string GetUniqueFemaleName()
	{
		string name = NameList.RandomName("Female");

		return name;
	}

	public static Vector3 GetVector3(Point3D p)
	{
		return new Vector3((float)p.X, (float)p.Y, (float)p.Z);
	}

	public static IEnumerator Wait(int Sec)
	{
		yield return new WaitForSeconds(Sec);
	}

	// this is to pad the technology name and cost together to a fixed length string
	// fixed space font such as Courier is needed
	public static string SplitPadName(string name, double cost, int length)
	{
		string result = name.Trim();
		string scost = ((int)cost).ToString() + "g ";
		scost = scost.PadLeft((length - result.Length), ' ');
		
		result += scost;

		return result;
	}

	public static string SplitPadName(string name1, string name2, int length)
	{
		string result = name1.Trim();

		name2 = name2.PadLeft((length - result.Length), ' ');
		result += name2;

		return result;
	}

	public static string SplitName(string name)
	{
		string result = "";
		List<int> pos = new List<int>();
		int i = 0;

		foreach (Char c in name.Trim())
		{
			if (Char.IsUpper(c))
				pos.Add(i);

			i++;
		}

		pos.Add(name.Length);

		i = 0;
		int k = 0;
		foreach (int j in pos)
		{
			result += name.Substring(i, j - i);
			if (k < pos.Count)
				result += " ";
			i = j;
			k++;
		}

		return result;
	}
}
